const http = require('http')
const context = require('./context')
const request = require('./request')
const response = require('./response')

class MyKoa{
    constructor() {
        this.middlewares = []
    }
    listen(...args) {
        const server = http.createServer(async (req, res) => {
            const ctx = this.createContext(req, res)

            const fn = this.compose(this.middlewares)
            await fn(ctx)

            res.end(ctx.body)
        })  
        server.listen(...args)
    }

    compose(mids) {
        return (ctx) => {
            // 支持用户手动想下调用
            let dispatch = (i) => {
                let fn = mids[i]
                if (!fn) {
                    return Promise.resolve()
                }
                let next = () => {
                    return dispatch(i+1)
                }
                return Promise.resolve(fn(ctx, next))
            }
    
            // 默认调用第一个函数
            return dispatch(0)
        }
    }

    createContext(req, res) {
        const ctx = Object.create(context)
        ctx.request = Object.create(request)
        ctx.response = Object.create(response)

        ctx.req = req
        ctx.request.req = req

        ctx.res = res
        ctx.response.res = res
        return ctx
    }
    use(middleware) {
        this.middlewares.push(middleware)
    }
}

module.exports = MyKoa